% Cross validation
[AllDataSampler] = Ddavid_cross_validation_training_testing(AllData, 10);
FoldNumber = 1;
[AllDataTraining, AllDataTesting, TrueLabelTraining, TrueLabelTesting] = Ddavid_pick_up_fold(AllData, TrueLabel, AllDataSampler, FoldNumber);

% Sampling training and testing
SizeDataTraining = 400;
[AllDataTraining, AllDataTesting, TrueLabelTraining, TrueLabelTesting, AllDataSampler] = Ddavid_sample_training_testing(AllData, TrueLabel, SizeDataTraining);

% Sampling incomplete labels
SampledDataSize = 100;
SampledLabelSize = 30;

[SampledTrueLabelTraining, SampledDataTraining, SampledOnlyTrueLabelTraining, DataSampler] = Ddavid_sample_label(AllDataTraining, TrueLabelTraining, SampledDataSize, SampledLabelSize);
AllData = [AllDataTraining; AllDataTesting];
TrueLabel = [TrueLabelTraining; TrueLabelTesting];

% SampledTrueLabelTesting = ones(size(TrueLabelTesting, 1), size(TrueLabelTesting, 2)) * (-1);
% SampledTrueLabel = [SampledTrueLabelTraining; SampledTrueLabelTesting];

% All training data
[Prior, PriorN, Cond, CondN] = MLKNN_train(AllDataTraining, TrueLabelTraining', 3, 1);
[AllResult.HammingLoss, AllResult.RankingLoss, AllResult.OneError, AllResult.Coverage, AllResult.Average_Precision, AllResult.Outputs, AllResult.Pre_Labels] = MLKNN_test(AllDataTraining, TrueLabelTraining', AllDataTesting, TrueLabelTesting', 3, Prior, PriorN, Cond, CondN);

% Recoverd training data
K = 3;
R = 0.0;
T = 1;
Method = 2;

KNNList = Ddavid_find_knn(K, AllDataTraining);

[HammingLoss, HammingLossBefore, RecoveredTrueLabelTraining] = Ddavid_recover_multi_label(AllDataTraining, TrueLabelTraining, SampledTrueLabelTraining, K, KNNList, R, T, Method);
% [Prior, PriorN, Cond, CondN] = MLKNN_train(AllDataTraining, RecoveredTrueLabelTraining', K, 1);
% [RecoverdResult.HammingLoss, RecoverdResult.RankingLoss, RecoverdResult.OneError, RecoverdResult.Coverage, RecoverdResult.Average_Precision, RecoverdResult.Outputs, RecoverdResult.Pre_Labels] = MLKNN_test(AllDataTraining, RecoveredTrueLabelTraining', AllDataTesting, TrueLabelTesting', K, Prior, PriorN, Cond, CondN);

AddedPoint.NumberTraining = sum(sum(RecoveredTrueLabelTraining ~= SampledTrueLabelTraining));
AddedPoint.CorrectNumberTraining = sum(sum((RecoveredTrueLabelTraining == 1) & (SampledTrueLabelTraining == -1) & (TrueLabelTraining == 1)));
AddedPoint.CorrectRateTraining = AddedPoint.CorrectNumberTraining / AddedPoint.NumberTraining;

[RecoveredDataTraining, RecoveredTrueLabelTraining] = Ddavid_remove_no_label_training(AllDataTraining, RecoveredTrueLabelTraining);
[Prior, PriorN, Cond, CondN] = MLKNN_train(RecoveredDataTraining, RecoveredTrueLabelTraining', K, 1);
[RecoverdResult.HammingLoss, RecoverdResult.RankingLoss, RecoverdResult.OneError, RecoverdResult.Coverage, RecoverdResult.Average_Precision, RecoverdResult.Outputs, RecoverdResult.Pre_Labels] = MLKNN_test(RecoveredDataTraining, RecoveredTrueLabelTraining', AllDataTesting, TrueLabelTesting', K, Prior, PriorN, Cond, CondN);

% All Sampled training data
K = 5;

[Prior, PriorN, Cond, CondN] = MLKNN_train(AllDataTraining, SampledTrueLabelTraining', K, 1);
[SampledResult.HammingLoss, SampledResult.RankingLoss, SampledResult.OneError, SampledResult.Coverage, SampledResult.Average_Precision, SampledResult.Outputs, SampledResult.Pre_Labels] = MLKNN_test(AllDataTraining, SampledTrueLabelTraining', AllDataTesting, TrueLabelTesting', 3, Prior, PriorN, Cond, CondN);

% Lazy
KNNList = Ddavid_find_knn(K, AllData);

[HammingLoss, HammingLossBefore, RecoveredTrueLabel] = Ddavid_recover_multi_label(AllData, TrueLabel, SampledTrueLabel, K, KNNList, R, T, Method);
RecoveredTrueLabelTesting = RecoveredTrueLabel((size(AllDataTraining, 1) + 1):(size(RecoveredTrueLabel, 1)), :);
HammingLossTesting = Hamming_loss(RecoveredTrueLabelTesting', TrueLabelTesting');

AddedPoint.NumberAll = sum(sum(RecoveredTrueLabel ~= SampledTrueLabel));
AddedPoint.CorrecNumbertAll = sum(sum((RecoveredTrueLabel == 1) & (SampledTrueLabel == -1) & (TrueLabel == 1)));
AddedPoint.CorrectRateAll = AddedPoint.CorrecNumbertAll / AddedPoint.NumberAll;
AddedPoint.NumberTesting = sum(sum(RecoveredTrueLabelTesting ~= SampledTrueLabelTesting));
AddedPoint.CorrectNumberTesting = sum(sum((RecoveredTrueLabelTesting == 1) & (SampledTrueLabelTesting == -1) & (TrueLabelTesting == 1)));
AddedPoint.CorrectRateTesting = AddedPoint.CorrectNumberTesting / AddedPoint.NumberTesting;

% MLNN
SizeTrainingData = size(AllDataTraining, 1);
SizeLabeledTrainingData = size(SampledDataTraining, 1);
TrainingKNNList = Ddavid_find_knn(SizeTrainingData - 1, AllDataTraining);
LabeledTrainingKNNList = Ddavid_find_knn(SizeLabeledTrainingData - 1, SampledDataTraining);
TestingKNNList = Ddavid_find_knn_from_training_data(SizeTrainingData, AllDataTesting, AllDataTraining);
LabeledTestingKNNList = Ddavid_find_knn_from_training_data(SizeLabeledTrainingData, AllDataTesting, SampledDataTraining);

K = 5;
KL = 1;

[PriorProb, CondKNNTable, CondLabeledRanksTable] = Ddavid_MLkLNN_Training(SampledTrueLabelTraining, SampledOnlyTrueLabelTraining, K, KL, TrainingKNNList, LabeledTrainingKNNList);
[FeaturesKNNTesting, Result] = Ddavid_MLkLNN_Testing(SampledTrueLabelTraining, SampledOnlyTrueLabelTraining, PriorProb, CondKNNTable, CondLabeledRanksTable, TrueLabelTesting, K, KL, TestingKNNList, LabeledTestingKNNList);

MLkLNN.RankingLoss = Ranking_loss(Result', TrueLabelTesting');
MLkLNN.OneError = One_error(Result', TrueLabelTesting');
MLkLNN.Coverage = coverage(Result', TrueLabelTesting');
MLkLNN.Average_Precision = Average_precision(Result', TrueLabelTesting');



% Only Sampled training data MLkNN
K = 5;

[ResultSampled.Prior, ResultSampled.PriorN, ResultSampled.Cond, ResultSampled.CondN] = MLKNN_train(SampledDataTraining, SampledOnlyTrueLabelTraining', K, 1);
[ResultSampled.HammingLoss, ResultSampled.RankingLoss, ResultSampled.OneError, ResultSampled.Coverage, ResultSampled.Average_Precision, ResultSampled.Outputs, ResultSampled.Pre_Labels] = MLKNN_test(SampledDataTraining, SampledOnlyTrueLabelTraining', AllDataTesting, TrueLabelTesting', K, ResultSampled.Prior, ResultSampled.PriorN, ResultSampled.Cond, ResultSampled.CondN);

% Only Sampled training data MLkNN with distribution features
SizeTrainingData = size(AllDataTraining, 1);
SizeTestingData = size(AllDataTesting, 1);
SizeLabel = size(SampledTrueLabelTraining, 2);
[TrainingKNNList, TrainingSortedDistTable] = Ddavid_find_knn(SizeTrainingData - 1, AllDataTraining);
[TestingKNNList, TestingSortedDistTable] = Ddavid_find_knn_from_training_data(SizeTrainingData, AllDataTesting, AllDataTraining);

K = 5;
KL = 1;

%%% Get distribution features
[DistributionFeatures] = Ddavid_get_distribution_features(SampledTrueLabelTraining, DataSampler, SizeLabel, TrainingKNNList, TestingKNNList, TrainingSortedDistTable, TestingSortedDistTable, K, KL);

%%% UsingFeatureLabeledRank, UsingFeatureDensity, UsingFeatureCommonNeighbor
FeatureUsingList = [1 0 0];
[Result100] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);

FeatureUsingList = [0 1 0];
[Result010] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);

FeatureUsingList = [0 0 1];
[Result001] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);

FeatureUsingList = [1 1 0];
[Result110] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);

FeatureUsingList = [1 0 1];
[Result101] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);

FeatureUsingList = [0 1 1];
[Result011] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);

FeatureUsingList = [1 1 1];
[Result111] = Ddavid_MLkNN_with_distribution_features(AllDataTraining, AllDataTesting, DataSampler, SampledOnlyTrueLabelTraining, TrueLabelTesting, K, DistributionFeatures, FeatureUsingList);



% WELL with distribution features
TrainingSize = size(AllDataTraining, 1);
TestingSize = size(AllDataTesting, 1);
LabelSize = size(TrueLabelTraining, 2);

AllData = [AllDataTraining; AllDataTesting];
TrueLabel = [TrueLabelTraining; TrueLabelTesting];
TrueLabel = double(TrueLabel == 1);
SampledTrueLabel = [SampledTrueLabelTraining; ones(TestingSize, LabelSize) * (-1)];
SampledTrueLabel = double(SampledTrueLabel == 1);

% AllData = AllDataTraining;
% TrueLabel = double(TrueLabelTraining == 1);
% SampledTrueLabel = double(SampledTrueLabelTraining == 1);

FeatureUsingList = [1 0 0];
AllDataTraining2 = AllDataTraining;
AllDataTesting2 = AllDataTesting;
if(FeatureUsingList(1) == 1)
    AllDataTraining2 = [AllDataTraining2 DistributionFeatures.TrainingLabeledRanksTable];
    AllDataTesting2 = [AllDataTesting2 DistributionFeatures.TestingLabeledRanksTable];
end
if(FeatureUsingList(2) == 1)
    AllDataTraining2 = [AllDataTraining2 DistributionFeatures.TrainingDensityTable];
    AllDataTesting2 = [AllDataTesting2 DistributionFeatures.TestingDensityTable];
end
if(FeatureUsingList(3) == 1)
    AllDataTraining2 = [AllDataTraining2 DistributionFeatures.TrainingCommonNeighborTable];
    AllDataTesting2 = [AllDataTesting2 DistributionFeatures.TestingCommonNeighborTable];
end
AllData = [AllDataTraining2; AllDataTesting2];

gamma = 0.25;
alpha = 100;
beta = 10;
C = 100;

[Result, HL, micro_F, macro_F] = call_WELL(gamma, alpha, beta, C, TrueLabel, AllData, SampledTrueLabel);

Result = Result((TrainingSize + 1):(TrainingSize + TestingSize), :);
Result(Result == 0) = -1;

ResultWELL.HammingLoss = Hamming_loss(Result', TrueLabelTesting');
ResultWELL.RankingLoss = Ranking_loss(Result', TrueLabelTesting');
ResultWELL.OneError = One_error(Result', TrueLabelTesting');
ResultWELL.Coverage = coverage(Result', TrueLabelTesting');
ResultWELL.Average_Precision = Average_precision(Result', TrueLabelTesting');

% MLR_GL with distribution features
%%% Get distribution features
SizeTrainingData = size(AllDataTraining, 1);
SizeTestingData = size(AllDataTesting, 1);
SizeLabel = size(SampledTrueLabelTraining, 2);
[TrainingKNNList, TrainingSortedDistTable] = Ddavid_find_knn(SizeTrainingData - 1, AllDataTraining);
[TestingKNNList, TestingSortedDistTable] = Ddavid_find_knn_from_training_data(SizeTrainingData, AllDataTesting, AllDataTraining);

K = 5;
KL = 1;

[DistributionFeatures] = Ddavid_get_distribution_features(SampledTrueLabelTraining, DataSampler, SizeLabel, TrainingKNNList, TestingKNNList, TrainingSortedDistTable, TestingSortedDistTable, K, KL);

%%% UsingFeatureLabeledRank, UsingFeatureDensity, UsingFeatureCommonNeighbor
C = 100;
eta = 50;
Gamma = 0.001;

FeatureUsingList = [0 0 0];
[Result000] = Ddavid_MLR_GL_with_distribution_features(AllDataTraining, AllDataTesting, SampledTrueLabelTraining, TrueLabelTesting, DistributionFeatures, FeatureUsingList, C, eta, Gamma);
